#pragma once

#include<string>

#include<my_global.h>
#include<mysql.h>

#include"db_table.h"

namespace uhdpbs {
	namespace db {
		class table;
		class row;

		class connection {
		private:
			std::string sError;
			MYSQL* pMysqlConnection;

			unsigned long load_rows(table* request, std::string sql);
			unsigned long save_insert(row r);
			unsigned long save_update(row r);
			unsigned long save_delete(row r);
			unsigned long execute(std::string sql);

			std::string get_where(row r, std::string column);
			std::string get_escaped(std::string value);
			std::string get_sql_value(row r, std::string column, std::string value);


		public:
			connection();
			~connection();

			void load_meta_data(table* request);

			/**
			<summery>
				Opens a connection to the underlying database server with the supplied credentials using the specified database.
			</summery>
			<param name="host">Server/host name to connect to.</param>
			<param name="database">The active database to select.</param>
			<param name="user">The database user to login as.</param>
			<param name="password">The password for that user.</param>
			<returns>Returns true if connection successful.</returns>
			*/
			bool open(std::string host, std::string database, std::string user, std::string password);
			/**
			<summery>
				Closes the database connection.  It is CRITICAL that this is called before the end of execution so system
				reources can be released.  Failure to do so will result in memory leaks and possibly system crashes.
			</summery>
			*/
			void close();

			/**
			<summery>
				Loads the table object with rows from the database server.  Requests are made through adding a row to the table
				before the load request.  This row will consist of boolean logic where
					db.Column1 == Row1.Column1 AND db.Column2 == Row2.Column2 AND ... AND db.ColumnN == RowN.ColumnN
				The database's rows 
			</summery>
			<param name="request">The table to load.</param>
			*/
			unsigned long load(table* request, std::string order = "");
			/**
			<summery>
				Save the tables state back to the database.  For each table row, a create, update, delete, or no SQL action will 
				be taken depending on each rows status.

				Once a table has been saved, it clears it's status and *MUST BE LOADED* before use again.
			</summery>
			<param name="request">The table to save.</param>
			*/
			unsigned long save(table* tbl);

			/**
			<summery>
				Converts an SQL identifier that follows the lowercase, singular, and underscores (_) for spaces pattern.  For eaxmple:
					"Hello World!" = get_user_friendly_name("hello_World!")
			</summery>
			<param name="request">SQL name</param>
			<returns>Returns the user friendly name of the request.</returns>
			*/
			std::string get_user_freidnly_name(std::string sql);

			std::string get_error();
			void clear_error();
		};
	}
}